#include "key1.h"
#include "key_common.h"
#include "record.h"
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define GPIO_CHIP_LABEL "GPIOF"
#define GPIO_LINE 9
#define CONSUMER "key1"
#define API_KEY "1sy2fb2e6j7dmZqX9siYj6aa"
#define SECRET_KEY "uj7d4Z2XmdhMvum6qEzOcbsEMxtTC1iX"

typedef struct
{
    const char *pcm_device;
    unsigned int channels;
    unsigned int sample_rate;
    const char *filename;
} key1_thread_args_t;

/**
 * 按键1录音控制线程函数
 * @param args: 线程参数
 * @return: NULL
 */
static void *key1_thread_func(void *args)
{
    key1_thread_args_t *thread_args = (key1_thread_args_t *)args;

    // 初始化音频捕捉上下文
    audio_record_context_t *context = audio_record_init(thread_args->pcm_device, thread_args->channels, thread_args->sample_rate, thread_args->filename);
    if (!context)
    {
        fprintf(stderr, "初始化音频捕捉上下文失败\n");
        free(thread_args); // 释放内存
        return NULL;
    }

    // 初始化GPIO按键
    struct gpiod_line *line = gpio_init(GPIO_CHIP_LABEL, GPIO_LINE, CONSUMER);
    if (!line)
    {
        audio_record_cleanup(context); // 清理音频捕捉上下文
        free(thread_args);             // 释放内存
        return NULL;
    }

    pthread_detach(pthread_self()); // 在资源初始化后分离线程

    // 获取初始按键状态
    int last_value = gpiod_line_get_value(line);

    // 获取百度云Access Token
    char *token = baidu_get_access_token(API_KEY, SECRET_KEY);

    // 持续监控按键状态
    while (1)
    {
        int value = gpiod_line_get_value(line);

        if (value != last_value)
        {
            if (value == 0)
            {
                printf("按键按下，开始录音\n");
                audio_record_reinit(context, thread_args->pcm_device, thread_args->channels, thread_args->sample_rate, thread_args->filename);
                audio_record_start(context);
            }
            else
            {
                printf("按键释放，停止录音\n");
                audio_record_stop(context);

                // 调用语音识别API
                printf("开始语音识别...\n");
                long response_code = 0; // 初始化响应码
                char *recognition_result = baidu_recognize_speech(thread_args->filename, token, &response_code);

                if (recognition_result != NULL)
                {
                    if (response_code == 200)
                    {
                        char *result = extract_result(recognition_result);
                        if (result)
                        {
                            printf("识别结果：%s\n", result);
                            free(result);
                        }
                        else
                        {
                            fprintf(stderr, "Failed to extract result\n");
                        }
                    }
                    else
                    {
                        fprintf(stderr, "HTTP request failed with code %ld\n", response_code);
                    }
                    free(recognition_result);
                }
                else
                {
                    fprintf(stderr, "Failed to recognize speech\n");
                }
                free(recognition_result);
            }
            last_value = value;
        }
        usleep(100000); // 延迟100毫秒
    }

    // 关闭GPIO芯片
    gpiod_chip_close(gpiod_line_get_chip(line));
    audio_record_cleanup(context); // 清理音频捕捉上下文
    free(thread_args);             // 释放内存
    return NULL;
}

/**
 * 按键1控制录音
 * @param pcm_device: PCM设备名
 * @param channels: 声道数
 * @param sample_rate: 采样率
 * @param filename: 输出文件名
 */
void key1_record_control(const char *pcm_device, unsigned int channels, unsigned int sample_rate, const char *filename)
{
    pthread_t key1_thread;
    key1_thread_args_t *args = (key1_thread_args_t *)malloc(sizeof(key1_thread_args_t));
    if (!args)
    {
        perror("内存分配失败");
        return;
    }

    args->pcm_device = pcm_device;
    args->channels = channels;
    args->sample_rate = sample_rate;
    args->filename = filename;

    // 创建按键1录音控制线程
    if (pthread_create(&key1_thread, NULL, key1_thread_func, args) != 0)
    {
        perror("创建按键1录音控制线程失败");
        free(args); // 如果线程创建失败，释放内存
        return;
    }
}
